<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>视频压缩工具</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/ffmpeg/0.11.6/ffmpeg.min.js"></script>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
        font-family: 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', Arial,
          sans-serif;
      }

      :root {
        --primary-bg: #e6e7ee;
        --secondary-bg: #ffffff;
        --shadow-light: #ffffff;
        --shadow-dark: #d1d9e6;
        --accent-color: #667eea;
        --accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        --success-color: #4ecdc4;
        --danger-color: #ff6b6b;
        --warning-color: #feca57;
        --text-primary: #2d3748;
        --text-secondary: #718096;
        --glass-bg: rgba(255, 255, 255, 0.25);
        --glass-border: rgba(255, 255, 255, 0.18);
      }

      body {
        background: var(--primary-bg);
        color: var(--text-primary);
        min-height: 100vh;
        padding: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;
        transition: all 0.3s ease;
        animation: pageLoad 0.8s ease;
      }

      @keyframes pageLoad {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .container {
        width: 100%;
        max-width: 1200px;
        background: var(--primary-bg);
        border-radius: 30px;
        padding: 40px;
        box-shadow: 20px 20px 60px var(--shadow-dark),
          -20px -20px 60px var(--shadow-light);
        margin-top: 20px;
        transition: all 0.3s ease;
        animation: containerFloat 1s ease 0.2s both;
      }

      @keyframes containerFloat {
        from {
          opacity: 0;
          transform: translateY(30px) scale(0.95);
        }
        to {
          opacity: 1;
          transform: translateY(0) scale(1);
        }
      }

      .container:hover {
        box-shadow: 25px 25px 70px var(--shadow-dark),
          -25px -25px 70px var(--shadow-light);
      }

      header {
        text-align: center;
        margin-bottom: 40px;
        padding: 30px;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 10px 10px 20px var(--shadow-dark),
          -10px -10px 20px var(--shadow-light);
        animation: headerSlide 0.8s ease 0.4s both;
      }

      @keyframes headerSlide {
        from {
          opacity: 0;
          transform: translateY(-30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      h1 {
        font-size: 3.2rem;
        margin-bottom: 15px;
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
        font-weight: 700;
        animation: titleGlow 3s ease-in-out infinite alternate;
      }

      @keyframes titleGlow {
        from {
          filter: brightness(1);
        }
        to {
          filter: brightness(1.2);
        }
      }

      .subtitle {
        font-size: 1.3rem;
        color: var(--text-secondary);
        margin-bottom: 30px;
        font-weight: 500;
      }

      .panels {
        display: flex;
        gap: 30px;
        margin-bottom: 40px;
        animation: panelsSlide 0.8s ease 0.6s both;
      }

      @keyframes panelsSlide {
        from {
          opacity: 0;
          transform: translateX(-20px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      .panel {
        flex: 1;
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .panel::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: left 0.8s;
      }

      .panel:hover::before {
        left: 100%;
      }

      .panel:hover {
        transform: translateY(-5px);
        box-shadow: 16px 16px 32px var(--shadow-dark),
          -16px -16px 32px var(--shadow-light);
      }

      .panel-title {
        font-size: 1.6rem;
        margin-bottom: 25px;
        color: var(--accent-color);
        display: flex;
        align-items: center;
        font-weight: 600;
      }

      .panel-title::before {
        content: attr(data-icon);
        margin-right: 12px;
        font-size: 1.8rem;
        animation: iconBounce 2s ease-in-out infinite;
      }

      @keyframes iconBounce {
        0%,
        100% {
          transform: scale(1);
        }
        50% {
          transform: scale(1.1);
        }
      }

      .file-upload {
        border: 3px dashed var(--accent-color);
        border-radius: 25px;
        padding: 50px 40px;
        text-align: center;
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        margin-bottom: 25px;
        cursor: pointer;
        background: var(--primary-bg);
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light);
        position: relative;
        overflow: hidden;
      }

      .file-upload:hover {
        border-color: var(--success-color);
        transform: translateY(-5px) scale(1.02);
        box-shadow: inset 10px 10px 20px var(--shadow-dark),
          inset -10px -10px 20px var(--shadow-light),
          0 15px 40px rgba(102, 126, 234, 0.25), 0 5px 15px rgba(0, 0, 0, 0.1);
      }

      .file-upload.dragover {
        border-color: var(--success-color);
        background: rgba(78, 205, 196, 0.05);
        transform: scale(1.05);
        box-shadow: inset 12px 12px 24px var(--shadow-dark),
          inset -12px -12px 24px var(--shadow-light),
          0 20px 50px rgba(78, 205, 196, 0.3);
        animation: dragPulse 1s ease-in-out infinite;
      }

      @keyframes dragPulse {
        0%,
        100% {
          border-color: var(--success-color);
        }
        50% {
          border-color: var(--accent-color);
        }
      }

      .file-upload-content {
        position: relative;
        z-index: 1;
      }

      .file-upload-icon {
        font-size: 3.5rem;
        margin-bottom: 20px;
        display: block;
        animation: iconFloat 3s ease-in-out infinite;
        filter: drop-shadow(0 4px 8px rgba(102, 126, 234, 0.2));
      }

      @keyframes iconFloat {
        0%,
        100% {
          transform: translateY(0);
        }
        50% {
          transform: translateY(-10px);
        }
      }

      .file-upload-text {
        font-size: 1.4rem;
        font-weight: 600;
        color: var(--text-primary);
        margin-bottom: 10px;
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
      }

      .file-upload-subtext {
        font-size: 1.1rem;
        color: var(--text-secondary);
        margin-bottom: 20px;
        font-weight: 500;
      }

      .file-upload-formats {
        font-size: 0.9rem;
        color: var(--accent-color);
        font-weight: 500;
        padding: 8px 16px;
        background: rgba(102, 126, 234, 0.1);
        border-radius: 20px;
        display: inline-block;
        margin-bottom: 20px;
      }

      .file-upload input[type='file'] {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        opacity: 0;
        cursor: pointer;
        z-index: 2;
      }

      .video-preview {
        width: 100%;
        background: var(--primary-bg);
        border-radius: 20px;
        overflow: hidden;
        margin-top: 20px;
        box-shadow: inset 10px 10px 20px var(--shadow-dark),
          inset -10px -10px 20px var(--shadow-light);
        transition: all 0.3s ease;
      }

      .video-preview:hover {
        box-shadow: inset 12px 12px 24px var(--shadow-dark),
          inset -12px -12px 24px var(--shadow-light);
      }

      video {
        width: 100%;
        max-height: 300px;
        display: block;
        border-radius: 15px;
      }

      .compress-options {
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        margin-bottom: 30px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        animation: optionsSlide 0.8s ease 0.8s both;
      }

      @keyframes optionsSlide {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .options-title {
        font-size: 1.6rem;
        color: var(--accent-color);
        margin-bottom: 25px;
        font-weight: 600;
        display: flex;
        align-items: center;
      }

      .options-title::before {
        content: '⚙️';
        margin-right: 12px;
        font-size: 1.8rem;
      }

      .preset-buttons {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 15px;
        margin-bottom: 30px;
      }

      .preset-btn {
        background: var(--primary-bg);
        border: 2px solid rgba(102, 126, 234, 0.2);
        border-radius: 15px;
        padding: 20px;
        cursor: pointer;
        transition: all 0.3s ease;
        text-align: center;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      .preset-btn:hover {
        transform: translateY(-3px);
        border-color: var(--accent-color);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      .preset-btn.active {
        border-color: var(--accent-color);
        background: rgba(102, 126, 234, 0.1);
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      .preset-title {
        font-size: 1.1rem;
        font-weight: 600;
        color: var(--text-primary);
        margin-bottom: 8px;
      }

      .preset-desc {
        font-size: 0.9rem;
        color: var(--text-secondary);
        margin-bottom: 10px;
      }

      .preset-resolution {
        font-size: 0.85rem;
        color: var(--accent-color);
        font-weight: 500;
        background: rgba(102, 126, 234, 0.1);
        padding: 4px 8px;
        border-radius: 8px;
        display: inline-block;
      }

      .custom-options {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 20px;
        margin-top: 30px;
        padding-top: 30px;
        border-top: 2px solid rgba(102, 126, 234, 0.1);
      }

      .form-group {
        display: flex;
        flex-direction: column;
      }

      label {
        display: block;
        margin-bottom: 10px;
        color: var(--text-secondary);
        font-weight: 500;
        font-size: 0.95rem;
      }

      input,
      select {
        width: 100%;
        padding: 14px 18px;
        background: var(--primary-bg);
        border: none;
        border-radius: 15px;
        color: var(--text-primary);
        font-size: 1rem;
        font-weight: 500;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
      }

      input:focus,
      select:focus {
        outline: none;
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light),
          0 0 0 3px rgba(102, 126, 234, 0.2);
      }

      .video-info {
        background: var(--primary-bg);
        border-radius: 20px;
        padding: 25px;
        margin-bottom: 30px;
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light);
        display: none;
      }

      .info-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        gap: 15px;
      }

      .info-item {
        text-align: center;
        padding: 15px;
        background: var(--primary-bg);
        border-radius: 15px;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
      }

      .info-label {
        font-size: 0.85rem;
        color: var(--text-secondary);
        margin-bottom: 5px;
        font-weight: 500;
      }

      .info-value {
        font-size: 1rem;
        color: var(--text-primary);
        font-weight: 600;
      }

      button {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 14px 28px;
        border-radius: 15px;
        cursor: pointer;
        font-weight: 600;
        transition: all 0.3s ease;
        font-size: 1rem;
        flex-shrink: 0;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        position: relative;
        overflow: hidden;
      }

      button::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      button:hover::before {
        left: 100%;
      }

      button:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      button:active {
        transform: translateY(0);
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      button:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
        box-shadow: 4px 4px 8px var(--shadow-dark),
          -4px -4px 8px var(--shadow-light);
      }

      .btn-primary {
        background: var(--accent-gradient);
        color: white;
        padding: 16px 32px;
        font-size: 1.1rem;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
      }

      .btn-primary:hover {
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(102, 126, 234, 0.3);
      }

      .btn-success {
        background: linear-gradient(
          135deg,
          var(--success-color) 0%,
          #44a08d 100%
        );
        color: white;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
      }

      .progress-container {
        margin: 30px 0;
        animation: progressSlide 0.8s ease 1s both;
      }

      @keyframes progressSlide {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .progress-bar {
        height: 16px;
        background: var(--primary-bg);
        border-radius: 20px;
        overflow: hidden;
        margin-bottom: 15px;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        position: relative;
      }

      .progress-fill {
        height: 100%;
        background: var(--accent-gradient);
        width: 0%;
        transition: width 0.3s ease;
        border-radius: 20px;
        box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
        position: relative;
        overflow: hidden;
      }

      .progress-fill::after {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.3),
          transparent
        );
        animation: progressShine 2s infinite;
      }

      @keyframes progressShine {
        0% {
          left: -100%;
        }
        100% {
          left: 100%;
        }
      }

      .progress-text {
        text-align: center;
        font-size: 1rem;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .actions {
        display: flex;
        justify-content: center;
        gap: 25px;
        margin-top: 30px;
        animation: actionsSlide 0.8s ease 1.2s both;
      }

      @keyframes actionsSlide {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .status-message {
        min-height: 35px;
        margin: 20px 0;
        color: var(--accent-color);
        font-weight: 600;
        font-size: 1.1rem;
        transition: all 0.3s ease;
        text-align: center;
      }

      .status-message.processing {
        animation: statusPulse 1.5s ease-in-out infinite;
      }

      @keyframes statusPulse {
        0%,
        100% {
          opacity: 1;
        }
        50% {
          opacity: 0.6;
        }
      }

      .error-message {
        color: var(--danger-color);
        margin: 20px 0;
        min-height: 35px;
        font-weight: 600;
        font-size: 1.1rem;
        animation: errorShake 0.5s ease;
        text-align: center;
      }

      @keyframes errorShake {
        0%,
        100% {
          transform: translateX(0);
        }
        25% {
          transform: translateX(-5px);
        }
        75% {
          transform: translateX(5px);
        }
      }

      .result-section {
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        margin-top: 30px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        display: none;
        text-align: center;
      }

      .result-title {
        font-size: 1.4rem;
        color: var(--accent-color);
        margin-bottom: 20px;
        font-weight: 600;
      }

      .result-comparison {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 30px;
        margin-bottom: 30px;
      }

      .comparison-item {
        background: var(--primary-bg);
        border-radius: 20px;
        padding: 25px;
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light);
      }

      .comparison-title {
        font-size: 1.1rem;
        font-weight: 600;
        color: var(--text-primary);
        margin-bottom: 15px;
      }

      .comparison-stats {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 15px;
      }

      .stat-item {
        text-align: center;
        padding: 10px;
        background: var(--primary-bg);
        border-radius: 10px;
        box-shadow: 4px 4px 8px var(--shadow-dark),
          -4px -4px 8px var(--shadow-light);
      }

      .stat-label {
        font-size: 0.8rem;
        color: var(--text-secondary);
        margin-bottom: 5px;
      }

      .stat-value {
        font-size: 0.9rem;
        color: var(--text-primary);
        font-weight: 600;
      }

      .compression-ratio {
        background: var(--success-color);
        color: white;
        padding: 15px;
        border-radius: 15px;
        margin: 20px 0;
        font-size: 1.2rem;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      .compressed-preview {
        margin: 30px 0;
        animation: slideIn 0.5s ease;
      }

      .preview-title {
        font-size: 1.2rem;
        color: var(--accent-color);
        margin-bottom: 20px;
        font-weight: 600;
        text-align: center;
      }

      .preview-video-container {
        background: var(--primary-bg);
        border-radius: 20px;
        padding: 20px;
        box-shadow: inset 8px 8px 16px var(--shadow-dark),
          inset -8px -8px 16px var(--shadow-light);
        text-align: center;
      }

      .preview-video-container video {
        max-width: 100%;
        max-height: 400px;
        border-radius: 15px;
        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
      }

      .result-actions {
        display: flex;
        gap: 15px;
        justify-content: center;
        flex-wrap: wrap;
      }

      .btn-secondary {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 15px 30px;
        border-radius: 25px;
        font-size: 1rem;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.3s ease;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        display: flex;
        align-items: center;
        gap: 8px;
      }

      .btn-secondary:hover {
        transform: translateY(-2px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      .btn-secondary:active {
        transform: translateY(0);
        box-shadow: inset 4px 4px 8px var(--shadow-dark),
          inset -4px -4px 8px var(--shadow-light);
      }

      .instructions {
        background: var(--primary-bg);
        border-radius: 25px;
        padding: 30px;
        margin-top: 40px;
        box-shadow: 10px 10px 20px var(--shadow-dark),
          -10px -10px 20px var(--shadow-light);
        animation: instructionsSlide 0.8s ease 1.4s both;
      }

      @keyframes instructionsSlide {
        from {
          opacity: 0;
          transform: translateY(30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .instructions h3 {
        color: var(--accent-color);
        margin-bottom: 20px;
        font-size: 1.4rem;
        font-weight: 600;
      }

      .instructions ol {
        padding-left: 25px;
        margin-bottom: 20px;
      }

      .instructions li {
        margin-bottom: 12px;
        line-height: 1.7;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .instructions p {
        color: var(--text-secondary);
        font-style: italic;
        font-weight: 500;
        padding: 15px;
        background: rgba(102, 126, 234, 0.1);
        border-radius: 15px;
        border-left: 4px solid var(--accent-color);
      }

      footer {
        margin-top: 40px;
        text-align: center;
        color: var(--text-secondary);
        font-size: 0.95rem;
        padding: 25px;
        background: var(--primary-bg);
        border-radius: 20px;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        animation: footerFade 0.8s ease 1.6s both;
      }

      @keyframes footerFade {
        from {
          opacity: 0;
        }
        to {
          opacity: 1;
        }
      }

      /* 响应式设计 */
      @media (max-width: 1024px) {
        .container {
          padding: 30px;
          margin: 10px;
        }

        .panels {
          flex-direction: column;
        }

        h1 {
          font-size: 2.5rem;
        }

        .subtitle {
          font-size: 1.1rem;
        }

        .result-comparison {
          grid-template-columns: 1fr;
        }
      }

      @media (max-width: 768px) {
        .container {
          padding: 20px;
        }

        .preset-buttons {
          grid-template-columns: 1fr;
        }

        .custom-options {
          grid-template-columns: 1fr;
        }

        .actions {
          flex-direction: column;
          align-items: center;
        }

        h1 {
          font-size: 2rem;
        }

        .file-upload {
          padding: 30px 20px;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>🗜️ 视频压缩工具</h1>
        <p class="subtitle">基于 FFmpeg 的高质量视频压缩处理</p>
      </header>

      <div class="panels">
        <!-- 上传面板 -->
        <div class="panel">
          <div class="panel-title" data-icon="📁">文件上传</div>
          <div class="file-upload" id="uploadArea">
            <div class="file-upload-content">
              <span class="file-upload-icon">🎬</span>
              <div class="file-upload-text">拖拽视频文件到此处或点击上传</div>
              <div class="file-upload-subtext">支持所有主流视频格式</div>
              <div class="file-upload-formats">
                MP4, AVI, MOV, MKV, WMV, FLV, WebM, M4V, 3GP, TS, MTS
              </div>
              <input type="file" id="videoInput" accept="video/*" />
            </div>
          </div>
          <div class="video-preview" id="originalPreview">
            <p
              style="
                text-align: center;
                padding: 60px 20px;
                color: var(--text-secondary);
                font-size: 1.1rem;
              "
            >
              📺 视频预览区
            </p>
          </div>
        </div>

        <!-- 压缩设置面板 -->
        <div class="panel">
          <div class="panel-title" data-icon="⚙️">压缩设置</div>

          <!-- 视频信息 -->
          <div class="video-info" id="videoInfo">
            <div class="info-grid">
              <div class="info-item">
                <div class="info-label">分辨率</div>
                <div class="info-value" id="originalResolution">-</div>
              </div>
              <div class="info-item">
                <div class="info-label">文件大小</div>
                <div class="info-value" id="originalSize">-</div>
              </div>
              <div class="info-item">
                <div class="info-label">时长</div>
                <div class="info-value" id="videoDuration">-</div>
              </div>
              <div class="info-item">
                <div class="info-label">码率</div>
                <div class="info-value" id="videoBitrate">-</div>
              </div>
            </div>
          </div>

          <!-- 预设选项 -->
          <div class="preset-buttons">
            <div class="preset-btn" data-preset="1080p">
              <div class="preset-title">全高清压缩</div>
              <div class="preset-desc">最佳画质</div>
              <div class="preset-resolution">1920×1080</div>
            </div>
            <div class="preset-btn" data-preset="720p">
              <div class="preset-title">高清压缩</div>
              <div class="preset-desc">适合网络分享</div>
              <div class="preset-resolution">1280×720</div>
            </div>
            <div class="preset-btn" data-preset="480p">
              <div class="preset-title">标清压缩</div>
              <div class="preset-desc">文件更小</div>
              <div class="preset-resolution">854×480</div>
            </div>
            <div class="preset-btn" data-preset="360p">
              <div class="preset-title">极限压缩</div>
              <div class="preset-desc">最小文件</div>
              <div class="preset-resolution">640×360</div>
            </div>
            <div class="preset-btn active" data-preset="custom">
              <div class="preset-title">自定义</div>
              <div class="preset-desc">手动设置参数</div>
              <div class="preset-resolution">自定义尺寸</div>
            </div>
          </div>

          <!-- 自定义选项 -->
          <div class="custom-options" id="customOptions">
            <div class="form-group">
              <label for="customWidth">宽度 (px)</label>
              <input
                type="number"
                id="customWidth"
                placeholder="如: 1280"
                min="1"
                max="4096"
              />
            </div>
            <div class="form-group">
              <label for="customHeight">高度 (px)</label>
              <input
                type="number"
                id="customHeight"
                placeholder="如: 720"
                min="1"
                max="4096"
              />
            </div>
            <div class="form-group">
              <label for="quality">质量等级</label>
              <select id="quality">
                <option value="23">高质量 (较大文件)</option>
                <option value="28" selected>平衡质量 (推荐)</option>
                <option value="32">低质量 (较小文件)</option>
              </select>
            </div>
            <div class="form-group">
              <label for="outputFormat">输出格式</label>
              <select id="outputFormat">
                <option value="mp4" selected>MP4 (推荐)</option>
                <option value="webm">WebM</option>
                <option value="avi">AVI</option>
              </select>
            </div>
          </div>
        </div>
      </div>

      <!-- 进度条 -->
      <div class="progress-container">
        <div class="progress-bar">
          <div class="progress-fill" id="progressFill"></div>
        </div>
        <div class="progress-text" id="progressText">🚀 准备就绪</div>
      </div>

      <!-- 状态信息 -->
      <div class="status-message" id="statusMessage"></div>
      <div class="error-message" id="errorMessage"></div>

      <!-- 操作按钮 -->
      <div class="actions">
        <button class="btn-primary" id="compressBtn" disabled>
          🗜️ 开始压缩
        </button>
        <button id="resetBtn">🔄 重置</button>
      </div>

      <!-- 结果展示 -->
      <div class="result-section" id="resultSection">
        <div class="result-title">✅ 压缩完成</div>
        <div class="result-comparison">
          <div class="comparison-item">
            <div class="comparison-title">原始视频</div>
            <div class="comparison-stats">
              <div class="stat-item">
                <div class="stat-label">文件大小</div>
                <div class="stat-value" id="originalFileSize">-</div>
              </div>
              <div class="stat-item">
                <div class="stat-label">分辨率</div>
                <div class="stat-value" id="originalRes">-</div>
              </div>
            </div>
          </div>
          <div class="comparison-item">
            <div class="comparison-title">压缩后</div>
            <div class="comparison-stats">
              <div class="stat-item">
                <div class="stat-label">文件大小</div>
                <div class="stat-value" id="compressedFileSize">-</div>
              </div>
              <div class="stat-item">
                <div class="stat-label">分辨率</div>
                <div class="stat-value" id="compressedRes">-</div>
              </div>
            </div>
          </div>
        </div>
        <div class="compression-ratio" id="compressionRatio">压缩比例: 0%</div>

        <!-- 压缩后视频预览 -->
        <div
          class="compressed-preview"
          id="compressedPreview"
          style="display: none"
        >
          <div class="preview-title">🎬 压缩后预览</div>
          <div class="preview-video-container" id="previewVideoContainer">
            <!-- 预览视频将在这里显示 -->
          </div>
        </div>

        <div class="result-actions">
          <button class="btn-secondary" id="previewBtn">👁️ 预览视频</button>
          <button class="btn-success" id="downloadBtn">📥 下载压缩视频</button>
        </div>
      </div>

      <!-- 使用说明 -->
      <div class="instructions">
        <h3>📖 使用说明</h3>
        <ol>
          <li>选择或拖拽视频文件到上传区域</li>
          <li>选择预设压缩方案或自定义压缩参数</li>
          <li>点击"开始压缩"按钮开始处理</li>
          <li>等待压缩完成后下载结果文件</li>
        </ol>
        <div
          class="warning-notice"
          style="
            background: rgba(255, 107, 107, 0.1);
            border: 2px solid var(--danger-color);
            border-radius: 15px;
            padding: 20px;
            margin: 20px 0;
            text-align: center;
          "
        >
          <h4
            style="
              color: var(--danger-color);
              margin-bottom: 10px;
              font-size: 1.2rem;
            "
          >
            ⚠️ 重要提示
          </h4>
          <p
            style="
              color: var(--danger-color);
              font-weight: 600;
              margin-bottom: 10px;
            "
          >
            1920*1080以上分辨率适配,此操作适用于较短视频（如1分钟以内）
          </p>
          <p style="color: var(--text-secondary); font-size: 0.95rem">
            处理长视频可能导致浏览器卡顿或崩溃，建议使用专业视频处理软件处理大文件
          </p>
        </div>
        <p>
          💡
          提示：较大的视频文件压缩时间会更长，请耐心等待。建议选择合适的质量等级以平衡文件大小和画质。
        </p>
      </div>

      <footer>
        <p>
          🛠️ 基于 FFmpeg.wasm 技术 | 所有处理均在浏览器本地完成，保护您的隐私
        </p>
      </footer>
    </div>

    <script>
      // 全局变量
      let ffmpeg = null
      let inputFile = null
      let compressedBlob = null
      let originalVideoInfo = {}
      const { createFFmpeg, fetchFile } = FFmpeg

      // DOM 元素
      const videoInput = document.getElementById('videoInput')
      const uploadArea = document.getElementById('uploadArea')
      const originalPreview = document.getElementById('originalPreview')
      const videoInfo = document.getElementById('videoInfo')
      const presetBtns = document.querySelectorAll('.preset-btn')
      const customOptions = document.getElementById('customOptions')
      const customWidth = document.getElementById('customWidth')
      const customHeight = document.getElementById('customHeight')
      const quality = document.getElementById('quality')
      const outputFormat = document.getElementById('outputFormat')
      const compressBtn = document.getElementById('compressBtn')
      const resetBtn = document.getElementById('resetBtn')
      const progressFill = document.getElementById('progressFill')
      const progressText = document.getElementById('progressText')
      const statusMessage = document.getElementById('statusMessage')
      const errorMessage = document.getElementById('errorMessage')
      const resultSection = document.getElementById('resultSection')
      const downloadBtn = document.getElementById('downloadBtn')
      const previewBtn = document.getElementById('previewBtn')
      const compressedPreview = document.getElementById('compressedPreview')
      const previewVideoContainer = document.getElementById(
        'previewVideoContainer'
      )

      // 初始化事件监听
      function initEvents() {
        // 文件上传事件
        videoInput.addEventListener('change', handleFileSelect)
        uploadArea.addEventListener('dragover', handleDragOver)
        uploadArea.addEventListener('drop', handleDrop)
        uploadArea.addEventListener('click', (e) => {
          // 只有在没有文件时才触发文件选择
          if (!inputFile && e.target === uploadArea) {
            videoInput.click()
          }
        })

        // 预设按钮事件
        presetBtns.forEach((btn) => {
          btn.addEventListener('click', () => selectPreset(btn.dataset.preset))
        })

        // 自定义尺寸输入事件
        customWidth.addEventListener('input', updateCustomPreset)
        customHeight.addEventListener('input', updateCustomPreset)

        // 按钮事件
        compressBtn.addEventListener('click', compressVideo)
        resetBtn.addEventListener('click', resetAll)
        downloadBtn.addEventListener('click', downloadCompressedVideo)
        previewBtn.addEventListener('click', previewCompressedVideo)
      }

      // 处理文件选择
      function handleFileSelect(e) {
        const file = e.target.files[0]
        if (file) {
          loadVideoFile(file)
        }
      }

      // 处理拖拽
      function handleDragOver(e) {
        e.preventDefault()
        uploadArea.classList.add('dragover')
      }

      function handleDrop(e) {
        e.preventDefault()
        uploadArea.classList.remove('dragover')
        const file = e.dataTransfer.files[0]
        if (file && file.type.startsWith('video/')) {
          videoInput.files = e.dataTransfer.files
          loadVideoFile(file)
        }
      }

      // 加载视频文件
      async function loadVideoFile(file) {
        try {
          inputFile = file

          // 显示视频预览
          const videoUrl = URL.createObjectURL(file)
          originalPreview.innerHTML = `
            <video controls style="width: 100%; border-radius: 15px;">
              <source src="${videoUrl}" type="${file.type}">
              您的浏览器不支持视频播放。
            </video>
          `

          // 获取视频信息
          const video = originalPreview.querySelector('video')
          video.addEventListener('loadedmetadata', () => {
            originalVideoInfo = {
              width: video.videoWidth,
              height: video.videoHeight,
              duration: video.duration,
              size: file.size,
            }

            updateVideoInfo()
            updateCustomDimensions()
            compressBtn.disabled = false
          })

          statusMessage.textContent = '✅ 视频加载成功，请选择压缩设置'
          errorMessage.textContent = ''
        } catch (error) {
          showError(`❌ 视频加载失败: ${error.message}`, errorMessage)
        }
      }

      // 更新视频信息显示
      function updateVideoInfo() {
        document.getElementById(
          'originalResolution'
        ).textContent = `${originalVideoInfo.width}×${originalVideoInfo.height}`
        document.getElementById('originalSize').textContent = formatFileSize(
          originalVideoInfo.size
        )
        document.getElementById('videoDuration').textContent = formatTime(
          originalVideoInfo.duration
        )
        document.getElementById('videoBitrate').textContent =
          Math.round(
            (originalVideoInfo.size * 8) / originalVideoInfo.duration / 1000
          ) + ' kbps'

        videoInfo.style.display = 'block'
      }

      // 选择预设
      function selectPreset(preset) {
        presetBtns.forEach((btn) => btn.classList.remove('active'))
        document
          .querySelector(`[data-preset="${preset}"]`)
          .classList.add('active')

        if (preset === 'custom') {
          customOptions.style.display = 'grid'
        } else {
          customOptions.style.display = 'none'

          // 设置预设尺寸
          const presets = {
            '1080p': { width: 1920, height: 1080 },
            '720p': { width: 1280, height: 720 },
            '480p': { width: 854, height: 480 },
            '360p': { width: 640, height: 360 },
          }

          if (presets[preset]) {
            customWidth.value = presets[preset].width
            customHeight.value = presets[preset].height
          }
        }
      }

      // 更新自定义预设
      function updateCustomPreset() {
        if (customWidth.value || customHeight.value) {
          selectPreset('custom')
        }
      }

      // 根据原视频尺寸更新自定义输入框
      function updateCustomDimensions() {
        if (!customWidth.value && !customHeight.value) {
          customWidth.value = originalVideoInfo.width
          customHeight.value = originalVideoInfo.height
        }
      }

      // 初始化 FFmpeg
      async function initFFmpeg() {
        if (!ffmpeg) {
          ffmpeg = createFFmpeg({
            log: true,
            progress: ({ ratio }) => {
              const percentage = Math.round(ratio * 100)
              progressFill.style.width = percentage + '%'
              progressText.textContent = `🔄 压缩中... ${percentage}%`
            },
          })

          statusMessage.textContent = '⏳ 正在初始化 FFmpeg...'
          statusMessage.classList.add('processing')

          await ffmpeg.load()

          statusMessage.textContent = '✅ FFmpeg 初始化完成'
          statusMessage.classList.remove('processing')
        }
      }

      // 压缩视频
      async function compressVideo() {
        if (!inputFile) {
          showError('❌ 请先选择视频文件', errorMessage)
          return
        }

        const width = parseInt(customWidth.value) || originalVideoInfo.width
        const height = parseInt(customHeight.value) || originalVideoInfo.height
        const crf = quality.value
        const format = outputFormat.value

        if (width <= 0 || height <= 0) {
          showError('❌ 请输入有效的宽度和高度', errorMessage)
          return
        }

        try {
          compressBtn.disabled = true
          errorMessage.textContent = ''
          resultSection.style.display = 'none'

          // 初始化 FFmpeg
          await initFFmpeg()

          statusMessage.textContent = '📤 正在上传文件...'
          statusMessage.classList.add('processing')

          // 写入输入文件
          const inputFileName = 'input.' + inputFile.name.split('.').pop()
          const outputFileName = `compressed.${format}`

          ffmpeg.FS('writeFile', inputFileName, await fetchFile(inputFile))

          statusMessage.textContent = '🔄 开始压缩处理...'

          // 构建 FFmpeg 命令
          const args = [
            '-i',
            inputFileName,
            '-vf',
            `scale=${width}:${height}`,
            '-c:v',
            'libx264',
            '-crf',
            crf,
            '-c:a',
            'aac',
            '-b:a',
            '128k',
            '-movflags',
            '+faststart',
            outputFileName,
          ]

          // 执行压缩
          await ffmpeg.run(...args)

          // 读取输出文件
          const data = ffmpeg.FS('readFile', outputFileName)
          compressedBlob = new Blob([data.buffer], { type: `video/${format}` })

          // 清理文件
          ffmpeg.FS('unlink', inputFileName)
          ffmpeg.FS('unlink', outputFileName)

          // 显示结果
          showCompressResult(width, height)

          statusMessage.textContent = '✅ 压缩完成！'
          statusMessage.classList.remove('processing')
          progressFill.style.width = '100%'
          progressText.textContent = '🎉 压缩完成'
        } catch (error) {
          console.error('压缩失败:', error)
          showError(`❌ 压缩失败: ${error.message}`, errorMessage)
          statusMessage.classList.remove('processing')
          compressBtn.disabled = false
        }
      }

      // 显示压缩结果
      function showCompressResult(width, height) {
        const originalSize = originalVideoInfo.size
        const compressedSize = compressedBlob.size
        const compressionRatio = Math.round(
          (1 - compressedSize / originalSize) * 100
        )

        // 更新结果显示
        document.getElementById('originalFileSize').textContent =
          formatFileSize(originalSize)
        document.getElementById(
          'originalRes'
        ).textContent = `${originalVideoInfo.width}×${originalVideoInfo.height}`
        document.getElementById('compressedFileSize').textContent =
          formatFileSize(compressedSize)
        document.getElementById(
          'compressedRes'
        ).textContent = `${width}×${height}`
        document.getElementById(
          'compressionRatio'
        ).textContent = `压缩比例: ${compressionRatio}% (节省 ${formatFileSize(
          originalSize - compressedSize
        )})`

        resultSection.style.display = 'block'
        compressBtn.disabled = false
      }

      // 预览压缩视频
      function previewCompressedVideo() {
        if (!compressedBlob) {
          showError('❌ 没有可预览的文件', errorMessage)
          return
        }

        // 创建视频元素
        const video = document.createElement('video')
        video.controls = true
        video.preload = 'metadata'
        video.style.maxWidth = '100%'
        video.style.maxHeight = '400px'
        video.style.borderRadius = '15px'
        video.style.boxShadow = '0 8px 20px rgba(0, 0, 0, 0.1)'

        // 设置视频源
        const videoUrl = URL.createObjectURL(compressedBlob)
        video.src = videoUrl

        // 清空预览容器并添加视频
        previewVideoContainer.innerHTML = ''
        previewVideoContainer.appendChild(video)

        // 显示预览区域
        compressedPreview.style.display = 'block'

        // 更新按钮文本
        previewBtn.textContent = '🔄 重新预览'

        statusMessage.textContent = '👁️ 视频预览已加载'

        // 视频加载完成后的处理
        video.addEventListener('loadedmetadata', () => {
          statusMessage.textContent = '✅ 预览就绪，可以播放视频'
        })

        // 视频加载错误处理
        video.addEventListener('error', () => {
          showError('❌ 视频预览加载失败', errorMessage)
          previewVideoContainer.innerHTML =
            '<p style="color: var(--danger-color); padding: 20px;">❌ 预览加载失败</p>'
        })
      }

      // 下载压缩视频
      function downloadCompressedVideo() {
        if (!compressedBlob) {
          showError('❌ 没有可下载的文件', errorMessage)
          return
        }

        const timestamp = new Date()
          .toISOString()
          .slice(0, 19)
          .replace(/:/g, '-')
        const format = outputFormat.value
        const filename = `compressed_${timestamp}.${format}`

        const a = document.createElement('a')
        a.href = URL.createObjectURL(compressedBlob)
        a.download = filename
        a.click()

        statusMessage.textContent = '📥 文件下载中...'
      }

      // 重置所有
      function resetAll() {
        if (confirm('🤔 确定要重置所有内容吗？')) {
          inputFile = null
          compressedBlob = null
          originalVideoInfo = {}

          videoInput.value = ''
          customWidth.value = ''
          customHeight.value = ''

          originalPreview.innerHTML =
            '<p style="text-align: center; padding: 60px 20px; color: var(--text-secondary); font-size: 1.1rem;">📺 视频预览区</p>'

          videoInfo.style.display = 'none'
          resultSection.style.display = 'none'
          compressedPreview.style.display = 'none'
          previewVideoContainer.innerHTML = ''
          previewBtn.textContent = '👁️ 预览视频'
          compressBtn.disabled = true

          statusMessage.textContent = ''
          statusMessage.classList.remove('processing')
          errorMessage.textContent = ''
          progressFill.style.width = '0%'
          progressText.textContent = '🚀 准备就绪'

          // 重置为自定义预设
          selectPreset('custom')
        }
      }

      // 显示错误信息
      function showError(message, element) {
        element.textContent = message
        element.classList.add('error-shake')
        setTimeout(() => {
          element.classList.remove('error-shake')
        }, 500)
      }

      // 格式化文件大小
      function formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes'
        const k = 1024
        const sizes = ['Bytes', 'KB', 'MB', 'GB']
        const i = Math.floor(Math.log(bytes) / Math.log(k))
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
      }

      // 格式化时间
      function formatTime(seconds) {
        if (!seconds || isNaN(seconds)) return '00:00'
        const mins = Math.floor(seconds / 60)
        const secs = Math.floor(seconds % 60)
        return `${mins.toString().padStart(2, '0')}:${secs
          .toString()
          .padStart(2, '0')}`
      }

      // 初始化
      initEvents()
      selectPreset('custom') // 默认选择自定义
    </script>
  </body>
</html>
